package main

import(
	"fmt"
	"reflect"
)

//演示反射
func reflectTest01(b interface{}){
	//1.先获取到 reflect.Type
	rTyp := reflect.TypeOf(b)
	fmt.Println(rTyp)

	//2.获取到 reflect.Value 此处的rVal底层不是 int类型 无法直接使用
	rVal := reflect.ValueOf(b)
	fmt.Printf("rVal=%v rVal type = %T \n",rVal,rVal)

	//n2 := 2 + rVal //此处会报错。
	//3.获取真正的reflect.Value
	n2 := 2 + rVal.Int() //直接获取真正的Value值
	fmt.Println(n2)

	//4.将rVal转成 interface{}
	iV := rVal.Interface()
	//将interface{} 通过断言转成需要的类型
	num2 := iV.(int)
	fmt.Println(num2)
}

//演示反射【对结构体的反射】
func reflectTest02(b interface{}){
	//1.先获取到 reflect.Type
	rTyp := reflect.TypeOf(b)
	fmt.Println(rTyp)

	//2.获取到 reflect.Value 此处的rVal底层不是 int类型 无法直接使用
	rVal := reflect.ValueOf(b)

	//3.获取变量对应的kind
	kind1 := rVal.Kind()
	kind2 := rTyp.Kind()
	fmt.Printf("kind =%v kind = %v \n",kind1,kind2)
	//4.将rVal转成 interface{}
	iV := rVal.Interface()
	//将interface{} 通过断言转成需要的类型
	fmt.Printf("iV = %v iV = %T\n",iV,iV)
	stu,ok := iV.(Student) //断言可以接收错误
	if ok{
		fmt.Println(stu.Name,ok)
	}
}

//通过反射修改num值
func reflect01(b interface{}){
	rVal := reflect.ValueOf(b)

	//看看 rVal kind 是
	fmt.Printf("rVal kind = %v",rVal.Kind())
	//设置num值
	// 等价于
	// num:=9
	//ptr *int = &num
	//num2:= *ptr  === rVal.Elem()
	rVal.Elem().SetInt(20)
}

type Student struct{
	Name string
	Age int
}

func main(){
	const(
		a = iota //递增赋值 第一个为0
		b //1
		c // 2
	)
	const(
		d = iota // 0
		e = iota // 1
		f , h = iota,iota // 2,2
	)
	fmt.Println(d,e,f,h)
	fmt.Println(a,b,c)
	//1.定义一个int
	var num int = 100
	reflectTest01(num)

	//2.定义一个Student的实例
	stu := Student {
		Name:"ddd",
		Age:20,
	}
	reflectTest02(stu)

	var nums int = 30
	reflect01(&nums)
	fmt.Println("num=",nums)
}